﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Activities;

namespace FusionDotNet.WorkflowActivities
{
    public abstract class FusionActivityBase<TReturnType, TResultType> : AsyncCodeActivity<TReturnType> where TResultType : CommandResult, new()
    {
        public OutArgument<bool> HasErrors { get; set; }
        public OutArgument<IEnumerable<Exception>> Exceptions { get; set; }

        public InArgument<FusionDotNet.AuthenticationToken> CommandAuthenticationToken { get; set; }

        public abstract Command<TResultType> CreateCommand(AsyncCodeActivityContext context);

        public abstract TReturnType CreateResult(TResultType commandResult);

        protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {
            var command = CreateCommand(context);

            FusionDotNet.AuthenticationToken token = context.GetValue(CommandAuthenticationToken);
            if (token != null)
            {
                command.AuthenticationToken = token;
            }

            context.UserState = command;

            return command.BeginExecute(callback, state);
        }

        protected override TReturnType EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
        {
            var command = context.UserState as Command<TResultType>;
            var commandResult = command.EndExecute(result);
            if (!commandResult.HasExceptions)
            {
                context.SetValue(HasErrors, false);
                return CreateResult(commandResult);
            }
            else
            {
                context.SetValue(HasErrors, true);
                context.SetValue(Exceptions, commandResult.ResultExceptions);
                return default(TReturnType);
            }
        }

    }
}
